import java.awt.*;
import java.util.LinkedList;

public class AbstractBiology {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int x;
    private int y;
    private int minX = 0;
    private int minY = 0;
    private int maxY = map[0].length;
    private int maxX = map.length;

    public void getMixorMaxAttactRanger(MedusaObjectManager medusaObjectManager) {
//        for (int i=0;i<enemyObject.enemyLinked.size();i++){
//            if (getY()==enemyObject.enemyLinked.get(i).getY()){
//                if (getX()>enemyObject.enemyLinked.get(i).getX()){
//                    minX=enemyObject.enemyLinked.get(i).getX();
//                }else if(getX()<enemyObject.enemyLinked.get(i).getX()){
//                    maxX=enemyObject.enemyLinked.get(i).getX();
//                }
//            }else if (getY()==enemyObject.enemyLinked.get(i).getX()){
//                if (getY()>enemyObject.enemyLinked.get(i).getY()){
//                    minY=enemyObject.enemyLinked.get(i).getY();
//                }else if(getY()<enemyObject.enemyLinked.get(i).getY()){
//                    maxY=enemyObject.enemyLinked.get(i).getY();
//                }
//            }
//        }
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    private boolean isSelected = false;
    private boolean isMove = false;
    private boolean isAttack = false;
    private String imagePath;
    private boolean isShowHP = false;
    private int moveType;
    static int map[][] = Maps.getMap();

    public int getMoveType() {
        return moveType;
    }

    public void setMoveType(int moveType) {
        this.moveType = moveType;
    }

    private int MaxHP = 100;

    public int getMaxHP() {
        return MaxHP;
    }

    private int HP = MaxHP;
    public int facesouth = 0;
    public int facewest = 1;
    public int faceeast = 2;
    public int facenorth = 3;
    public int face = facenorth;
    private int playermovestats = 0;

    public void updatePlayerMoveStats() {
        playermovestats = (playermovestats + 1) % 4;
    }

    public boolean isShowHP() {
        return isShowHP;
    }

    public void setShowHP(boolean showHP) {
        isShowHP = showHP;
    }

    public int getHP() {
        return HP;
    }

    public void setHP(int HP) {
        this.HP = HP;
    }

    public boolean isAttack() {
        return isAttack;
    }

    public void setAttack(boolean attack) {
        isAttack = attack;
    }

    private Color color;

    public boolean isMove() {
        return isMove;
    }

    public void setMove(boolean move) {
        isMove = move;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public AbstractBiology(int x, int y, Color color, String imagePath) {
        this.x = x;
        this.y = y;
        this.color = color;
        this.imagePath = imagePath;
    }

    public void setImagePath(String imagePath) {
        this.imagePath = imagePath;
    }

    private Image imageFace;

    public void setImageFace(String imageFace1) {
        imageFace = Toolkit.getDefaultToolkit().getImage(imageFace1);

        this.imageFace = imageFace;
    }

    public Image getImageFace() {
        return imageFace;
    }

    private MoveRange moveRange = new MoveRange();
    private AttackRange attackRange = new AttackRange();
    public Point canMoveorAttackPoint[][] = null;
    public int canMoveRanger[][] = null;
    public int canAttackRanger[][] = attackRange.getAttackRanger[0];

    public Point[][] getMoveorAttackPoint() {
        canMoveorAttackPoint = new Point[][]{
                {new Point(getX() - 3, getY() - 3), new Point(getX() - 2, getY() - 3), new Point(getX() - 1, getY() - 3), new Point(getX(), getY() - 3), new Point(getX() + 1, getY() - 3), new Point(getX() + 2, getY() - 3), new Point(getX() + 3, getY() - 3)},
                {new Point(getX() - 3, getY() - 2), new Point(getX() - 2, getY() - 2), new Point(getX() - 1, getY() - 2), new Point(getX(), getY() - 2), new Point(getX() + 1, getY() - 2), new Point(getX() + 2, getY() - 2), new Point(getX() + 3, getY() - 2)},
                {new Point(getX() - 3, getY() - 1), new Point(getX() - 2, getY() - 1), new Point(getX() - 1, getY() - 1), new Point(getX(), getY() - 1), new Point(getX() + 1, getY() - 1), new Point(getX() + 2, getY() - 1), new Point(getX() + 3, getY() - 1)},
                {new Point(getX() - 3, getY()), new Point(getX() - 2, getY()), new Point(getX() - 1, getY()), new Point(getX(), getY()), new Point(getX() + 1, getY()), new Point(getX() + 2, getY()), new Point(getX() + 3, getY())},
                {new Point(getX() - 3, getY() + 1), new Point(getX() - 2, getY() + 1), new Point(getX() - 1, getY() + 1), new Point(getX(), getY() + 1), new Point(getX() + 1, getY() + 1), new Point(getX() + 2, getY() + 1), new Point(getX() + 3, getY() + 1)},
                {new Point(getX() - 3, getY() + 2), new Point(getX() - 2, getY() + 2), new Point(getX() - 1, getY() + 2), new Point(getX(), getY() + 2), new Point(getX() + 1, getY() + 2), new Point(getX() + 2, getY() + 2), new Point(getX() + 3, getY() + 2)},
                {new Point(getX() - 3, getY() + 3), new Point(getX() - 2, getY() + 3), new Point(getX() - 1, getY() + 3), new Point(getX(), getY() + 3), new Point(getX() + 1, getY() + 3), new Point(getX() + 2, getY() + 3), new Point(getX() + 3, getY() + 3)}
        };
        return canMoveorAttackPoint;
    }

    private int count = 0;

    public void tick() {
        count++;
        if (count >= 20) {
            updatePlayerMoveStats();
            count = 0;
        }
        getMoveorAttackPoint();
        canMoveRanger = moveRange.getMoverange[getMoveType()];
    }

    public void isAttackFunction(java.awt.event.MouseEvent e, GameStats gameStats, MedusaObjectManager medusaObjectManager, DoraemonObjectManager doraemonObjectManager, Maps maps) {
        int eY = e.getX() / Global.CELL_SIZE;
        int eX = e.getY() / Global.CELL_SIZE;
        for (int i = 0; i < canMoveorAttackPoint.length; i++) {
            for (int j = 0; j < canMoveorAttackPoint[0].length; j++) {
                if (canAttackRanger[i][j] == 1 &&
                        canMoveorAttackPoint[i][j].x + maps.offsetY / Global.CELL_SIZE == e.getY() / Global.CELL_SIZE &&
                        canMoveorAttackPoint[i][j].y + maps.offsetX / Global.CELL_SIZE == e.getX() / Global.CELL_SIZE) {
                    for (int z = 0; z < medusaObjectManager.enemyLinked.size(); z++) {
                        if (eX == medusaObjectManager.enemyLinked.get(z).getX() + maps.offsetY / Global.CELL_SIZE &&
                                eY == medusaObjectManager.enemyLinked.get(z).getY() + maps.offsetX / Global.CELL_SIZE) {
                            maps.setCurrentTurnBaseStats(TurnBaseStats.playerAttck);
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e1) {
                                e1.printStackTrace();
                            }
                            maps.setCurrentTurnBaseStats(TurnBaseStats.nothing);
                            //JOptionPane.showMessageDialog(null,"敌人收到攻击");
                            medusaObjectManager.enemyLinked.get(z).setHP(medusaObjectManager.enemyLinked.get(z).getHP() - 10);
                        }
                    }

                }
            }
            setAttack(false);
        }
    }

    public boolean isCanMoveWest(DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        return isCanMove(doraemonObjectManager, medusaObjectManager, getY() - 1, getX());
    }

    public boolean isCanMoveEast(DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        return isCanMove(doraemonObjectManager, medusaObjectManager, getY() + 1, getX());
    }

    public boolean isCanMoveNorth(DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        return isCanMove(doraemonObjectManager, medusaObjectManager, getY(), getX() - 1);
    }

    public boolean isCanMoveSouth(DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        return isCanMove(doraemonObjectManager, medusaObjectManager, getY(), getX() + 1);
    }

    private boolean isCanMove(DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, int y, int i2) {
        boolean isCanMove = true;
        for (int i = 0; i < doraemonObjectManager.abstractBiologyLinked.size(); i++) {
            if (y == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && i2 == doraemonObjectManager.abstractBiologyLinked.get(i).getX()) {
                isCanMove = false;
            }
        }
        for (int i = 0; i < medusaObjectManager.enemyLinked.size(); i++) {
            if (y == medusaObjectManager.enemyLinked.get(i).getY() && i2 == medusaObjectManager.enemyLinked.get(i).getX()) {
                isCanMove = false;
            }
        }
        return isCanMove;
    }

    public boolean isPlayerCanMove(java.awt.event.MouseEvent e, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, Maps maps) {
        int screenY = getX() + maps.offsetY / Global.CELL_SIZE;
        int screenX = getY() + maps.offsetX / Global.CELL_SIZE;
        boolean isplayercanmove = false;
        for (int i = 0; i < medusaObjectManager.enemyLinked.size(); i++) {
            if (e.getX() / Global.CELL_SIZE == medusaObjectManager.enemyLinked.get(i).getY() + maps.offsetX / Global.CELL_SIZE && e.getY() / Global.CELL_SIZE == medusaObjectManager.enemyLinked.get(i).getX() + maps.offsetY / Global.CELL_SIZE) {
                isplayercanmove = true;
            }
        }
        for (int i = 0; i < doraemonObjectManager.abstractBiologyLinked.size(); i++) {
            if (e.getX() / Global.CELL_SIZE == doraemonObjectManager.abstractBiologyLinked.get(i).getY() + maps.offsetX / Global.CELL_SIZE && e.getY() / Global.CELL_SIZE == doraemonObjectManager.abstractBiologyLinked.get(i).getX() + maps.offsetY / Global.CELL_SIZE) {
                isplayercanmove = true;
            }
        }
        return isplayercanmove;
    }

    public int getPlayerNumber(DoraemonObjectManager doraemonObjectManager) {
        int playerNumber = Integer.MAX_VALUE;
        for (int i = 0; i < doraemonObjectManager.abstractBiologyLinked.size(); i++) {
            if (getY() - 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() == doraemonObjectManager.abstractBiologyLinked.get(i).getX()) {
                playerNumber = i;
            } else if (getY() + 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() == doraemonObjectManager.abstractBiologyLinked.get(i).getX()) {
                playerNumber = i;
            } else if (getY() == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() + 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getX()) {
                playerNumber = i;
            } else if (getY() == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() - 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getX()) {
                playerNumber = i;
            }
        }
        return playerNumber;
    }

    public boolean isHavePlayer(DoraemonObjectManager doraemonObjectManager) {
        boolean ishaveplayer = false;
        for (int i = 0; i < doraemonObjectManager.abstractBiologyLinked.size(); i++) {
            if (getY() + 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() == doraemonObjectManager.abstractBiologyLinked.get(i).getX() ||
                    getY() - 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() == doraemonObjectManager.abstractBiologyLinked.get(i).getX() ||
                    getY() == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() + 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getX() ||
                    getY() == doraemonObjectManager.abstractBiologyLinked.get(i).getY() && getX() - 1 == doraemonObjectManager.abstractBiologyLinked.get(i).getX()
            ) {
                ishaveplayer = true;
            }
        }
        return ishaveplayer;
    }

    //Thread thread = new Thread();
    public void enemyMove(Maps maps, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, Thread thread) throws InterruptedException {
        AbstractBiology tempAbstractBiology = null;
        int tempCount = Integer.MAX_VALUE;
        for (int i = 0; i < doraemonObjectManager.abstractBiologyLinked.size(); i++) {
            if ((Math.abs(doraemonObjectManager.abstractBiologyLinked.get(i).getX() - getX()) + Math.abs(doraemonObjectManager.abstractBiologyLinked.get(i).getY() - getY())) < tempCount) {
                tempCount = Math.abs(doraemonObjectManager.abstractBiologyLinked.get(i).getX() - getX()) + Math.abs(doraemonObjectManager.abstractBiologyLinked.get(i).getY() - getY());
                tempAbstractBiology = doraemonObjectManager.abstractBiologyLinked.get(i);
            }
        }
        thread.sleep(Global.ANIMATIONTIME);
        changeFace(tempAbstractBiology.getX(), tempAbstractBiology.getY());
        if (isHavePlayer(doraemonObjectManager)) {
            thread.sleep(Global.ANIMATIONTIME);
            setAttack(true);
            thread.sleep(Global.ANIMATIONTIME);
            setAttack(false);
            doraemonObjectManager.abstractBiologyLinked.get(getPlayerNumber(doraemonObjectManager)).setHP(doraemonObjectManager.abstractBiologyLinked.get(getPlayerNumber(doraemonObjectManager)).getHP() - 10);

            maps.setCurrentTurnBaseStats(TurnBaseStats.enemyAttck);
            //JOptionPane.showMessageDialog(null,"攻击玩家");
        } else {
            isHavePlayer(doraemonObjectManager);
            setSelected(true);
            thread.sleep(Global.ANIMATIONTIME);
            setSelected(false);
            setMove(true);
            thread.sleep(Global.ANIMATIONTIME);
            setMove(false);
            moveToDoraemon(maps, doraemonObjectManager, medusaObjectManager, tempAbstractBiology);
        }
        thread.sleep(300);
        changeFace(tempAbstractBiology.getX(), tempAbstractBiology.getY());

    }

    private void moveToDoraemon(Maps maps, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, AbstractBiology tempAbstractBiology) {
        LinkedList<AStarEntity> bestshortway = new AStarFindPath().AStartest(getX(), getY(),
                tempAbstractBiology.getX(), tempAbstractBiology.getY(), doraemonObjectManager, medusaObjectManager);
        for (int step = 0; step < bestshortway.size(); step++) {
            for (int i = 0; i < bestshortway.size(); i++) {
                if (bestshortway.get(i).getH() == step) {
                    for (int w = 0; w < canMoveorAttackPoint.length; w++) {
                        for (int d = 0; d < canMoveorAttackPoint[0].length; d++) {
                            if (canMoveorAttackPoint[w][d].x == bestshortway.get(i).getX() &&
                                    canMoveorAttackPoint[w][d].y == bestshortway.get(i).getY()) {
                                if (canMoveRanger[w][d] == 1) {
                                    changeFace(bestshortway.get(i).getX(), bestshortway.get(i).getY());
                                    setX(bestshortway.get(i).getX());
                                    setY(bestshortway.get(i).getY());

                                    System.out.println(step);
                                    if (isHavePlayer(doraemonObjectManager)) {
                                        changeFace(tempAbstractBiology.getX(), tempAbstractBiology.getY());
                                        setAttack(true);

                                        setAttack(false);
                                        doraemonObjectManager.abstractBiologyLinked.get(getPlayerNumber(doraemonObjectManager)).setHP(doraemonObjectManager.abstractBiologyLinked.get(getPlayerNumber(doraemonObjectManager)).getHP() - 10);
                                        maps.setCurrentTurnBaseStats(TurnBaseStats.enemyAttck);
                                        break;
//                                            Thread.sleep(1000);
//                                            maps.setMsg(Maps.msgenum.nothing);
                                        //JOptionPane.showMessageDialog(null,"攻击玩家");
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }
    }

    private void changeFace(int x, int y) {
        if (x > getX()) {
            face = facesouth;
        } else if (x < getX()) {
            face = facenorth;
        } else if (y > getY()) {
            face = faceeast;
        } else if (y < getY()) {
            face = facewest;
        }
    }

    public void playMove(java.awt.event.MouseEvent e, GameStats gameStats, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, Maps maps) {
        int screenY = getX() + maps.offsetY / Global.CELL_SIZE;
        int screenX = getY() + maps.offsetX / Global.CELL_SIZE;
        getMixorMaxAttactRanger(medusaObjectManager);
        if (true/*e.getX()/60>=0&&e.getX()/60<Maps.map[0].length&&e.getY()/60>=0&&e.getY()/60<Maps.map.length*/) {
            if (isMove()) {
                isMoveFunction(e, doraemonObjectManager, medusaObjectManager, maps, screenY, screenX);
            }
            if (isAttack) {
                isAttackFunction(e, gameStats, medusaObjectManager, doraemonObjectManager, maps);
            }
            if (isSelected) {
                isSelectedFunction(e, gameStats, maps, screenY, screenX);
            }
            doraemonObjectManager.selectPlayer(e, maps);
        }
    }

    private void isSelectedFunction(java.awt.event.MouseEvent e, GameStats gameStats, Maps maps, int screenY, int screenX) {
        if (e.getX() / Global.CELL_SIZE == screenX - 1 && e.getY() / Global.CELL_SIZE == screenY + 1) {
            setMove(true);
            setSelected(false);
        } else if (e.getX() / Global.CELL_SIZE == screenX + 1 && e.getY() / Global.CELL_SIZE == screenY + 1) {
            gameStats.CURRENTSTATS = gameStats.ENEMYTURN;
            setSelected(false);
            setMove(false);
            maps.setCurrentTurnBaseStats(TurnBaseStats.enemyturn);
            //JOptionPane.showMessageDialog(null,"敌人回合");
        } else if (e.getX() / Global.CELL_SIZE == screenX && e.getY() / Global.CELL_SIZE == screenY + 1) {
            setAttack(true);
            setSelected(false);
        }
    }

    private void isMoveFunction(java.awt.event.MouseEvent e, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager, Maps maps, int screenY, int screenX) {
        for (int i = 0; i < canMoveorAttackPoint.length; i++) {
            for (int j = 0; j < canMoveorAttackPoint[0].length; j++) {
                if (canMoveRanger[i][j] == 1 && e.getY() / Global.CELL_SIZE == canMoveorAttackPoint[i][j].x + maps.offsetY / Global.CELL_SIZE
                        && e.getX() / Global.CELL_SIZE == canMoveorAttackPoint[i][j].y + maps.offsetX / Global.CELL_SIZE) {
                    if (isPlayerCanMove(e, doraemonObjectManager, medusaObjectManager, maps) == false) {
                        int posX = e.getY() / Global.CELL_SIZE;
                        int posY = e.getX() / Global.CELL_SIZE;

                        setDoraemonStopFace(screenY, screenX, posX, posY);
                        setY(getY() + (e.getX() / Global.CELL_SIZE - screenX));
                        setX(getX() + (e.getY() / Global.CELL_SIZE - screenY));
                        setMove(false);
                    }

                }
            }
        }
    }

    private void setDoraemonStopFace(int screenY, int screenX, int posX, int posY) {
        if (screenY == posX) {
            adjustFace(screenX, posY, faceeast, facewest);
        } else if (screenX == posY) {
            adjustFace(screenY, posX, facesouth, facenorth);
        } else if (posX < screenY) {
            if (posY > screenX) {
                adjustFace(screenY - posX, posY - screenX, faceeast, facenorth);
            } else if (posY < screenX) {
                adjustFace(screenY - posX, screenX - posY, facewest, facenorth);
            }
        } else if (posX > screenY) {
            if (posY > screenX) {
                adjustFace(posX - screenY, posY - screenX, faceeast, facesouth);
            } else if (posY < screenX) {
                adjustFace(posX - screenY, screenX - posY, facewest, facesouth);
            }
        }
    }

    private void adjustFace(int screenX, int posY, int faceeast, int facewest) {
        if (posY > screenX) {
            face = faceeast;
        } else {
            face = facewest;
        }
    }

    public boolean isCanAttackEnemy(MedusaObjectManager medusaObjectManager) {
        for (int i = 0; i < canMoveorAttackPoint.length; i++) {
            for (int j = 0; j < canMoveorAttackPoint[0].length; j++) {
                if (canMoveorAttackPoint[i][j].x > minX && canMoveorAttackPoint[i][j].y > minY
                        && canMoveorAttackPoint[i][j].x < maxX && canMoveorAttackPoint[i][j].y < maxY
                        && canAttackRanger[i][j] == 1) {
                    for (int z = 0; z < medusaObjectManager.enemyLinked.size(); z++) {
                        if (canMoveorAttackPoint[i][j].x == medusaObjectManager.enemyLinked.get(z).getX() &&
                                canMoveorAttackPoint[i][j].y == medusaObjectManager.enemyLinked.get(z).getY()) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    public void render(Graphics g, Maps maps, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        Image image1 = Toolkit.getDefaultToolkit().getImage("image/move.png");
        Image image2 = Toolkit.getDefaultToolkit().getImage("image/attack.png");
        Image image3 = Toolkit.getDefaultToolkit().getImage("image/over.png");
        if (isAttack() && isCanAttackEnemy(medusaObjectManager)) {
            isAttackRenderFunction(g, maps);
        }
        if (isSelected) {
            isSelectedRenderFunction(g, maps, medusaObjectManager, image1, image2, image3);
        }
        if (isMove) {
            isMoveRenderFunction(g, maps, doraemonObjectManager, medusaObjectManager);
        }
        if (isShowHP()) {
            isShowHpRenderFunction(g);
        }
        drawObjectRenderFunction(g, maps);
    }

    private void drawObjectRenderFunction(Graphics g, Maps maps) {
        g.setColor(color);
        Image image = Toolkit.getDefaultToolkit().getImage(imagePath);
        image.getHeight(null);
        image.getWidth(null);
        g.drawImage(image, y * Global.CELL_SIZE + maps.offsetX, x * Global.CELL_SIZE + maps.offsetY,
                (y + 1) * Global.CELL_SIZE + maps.offsetX, (x + 1) * Global.CELL_SIZE + maps.offsetY,
                image.getWidth(null) / 4 * (playermovestats), image.getHeight(null) / 4 * (face),
                image.getWidth(null) / 4 * (playermovestats + 1), image.getHeight(null) / 4 * (face + 1), null);
    }

    private void isShowHpRenderFunction(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillRect(3 * Global.CELL_SIZE, 1 * Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE);
        Image image = Toolkit.getDefaultToolkit().getImage(imagePath);
        g.drawImage(image, 3 * Global.CELL_SIZE, 1 * Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, null);
        g.fill3DRect(4 * Global.CELL_SIZE, 1 * Global.CELL_SIZE, 6 * Global.CELL_SIZE, Global.CELL_SIZE, true);
        g.setColor(Color.red);
        g.fill3DRect(4 * Global.CELL_SIZE, 1 * Global.CELL_SIZE, 6 * getHP() * Global.CELL_SIZE, Global.CELL_SIZE, true);
    }

    private void isMoveRenderFunction(Graphics g, Maps maps, DoraemonObjectManager doraemonObjectManager, MedusaObjectManager medusaObjectManager) {
        getMixorMaxAttactRanger(medusaObjectManager);
        g.setColor(new Color(237, 67, 90, 100));
        for (int i = 0; i < canMoveorAttackPoint.length; i++) {
            for (int j = 0; j < canMoveorAttackPoint[0].length; j++) {
                if (canMoveorAttackPoint[i][j].x > minX && canMoveorAttackPoint[i][j].y > minY
                        && canMoveorAttackPoint[i][j].x < maxX && canMoveorAttackPoint[i][j].y < maxY
                        && canMoveRanger[i][j] == 1 && doraemonObjectManager.isHaveplayerInHere(canMoveorAttackPoint[i][j].x, canMoveorAttackPoint[i][j].y) == false
                        && medusaObjectManager.isHaveEnmeyInHere(canMoveorAttackPoint[i][j].x, canMoveorAttackPoint[i][j].y) == false) {
                    g.fill3DRect(canMoveorAttackPoint[i][j].y * Global.CELL_SIZE + maps.offsetX, canMoveorAttackPoint[i][j].x * Global.CELL_SIZE + maps.offsetY,
                            Global.CELL_SIZE, Global.CELL_SIZE, true);
                }
            }
        }
    }

    private void isSelectedRenderFunction(Graphics g, Maps maps, MedusaObjectManager medusaObjectManager, Image image1, Image image2, Image image3) {
        g.setColor(new Color(33, 18, 143, 100));
        g.fillRect((getY() - 1) * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE);
        g.drawImage(image1, (getY() - 1) * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE, null);
        if (isCanAttackEnemy(medusaObjectManager)) {
            g.fillRect(getY() * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE);
            g.drawImage(image2, (getY()) * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE, null);
        }
        g.fillRect((getY() + 1) * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE);
        g.drawImage(image3, (getY() + 1) * Global.CELL_SIZE + maps.offsetX, (getX() + 1) * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE, null);
    }

    private void isAttackRenderFunction(Graphics g, Maps maps) {
        g.setColor(new Color(237, 67, 90, 150));
        for (int i = 0; i < canMoveorAttackPoint.length; i++) {
            for (int j = 0; j < canMoveorAttackPoint[0].length; j++) {
                if (canMoveorAttackPoint[i][j].x > minX && canMoveorAttackPoint[i][j].y > minY
                        && canMoveorAttackPoint[i][j].x < maxX && canMoveorAttackPoint[i][j].y < maxY
                        && canAttackRanger[i][j] == 1) {
                    g.fillRect(canMoveorAttackPoint[i][j].y * Global.CELL_SIZE + maps.offsetX, canMoveorAttackPoint[i][j].x * Global.CELL_SIZE + maps.offsetY, Global.CELL_SIZE, Global.CELL_SIZE);
                }
            }
        }
    }
}
